#include "mystdlib.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
const char* toString(int code)
{
    if (code == LINE_FLUSH)
    {
        return "LINE_FLUSH";
    }
    if (code == FULL_FLUSH)
        return "FULL_FLUSH";
    if (code == NO_FLUSH)
        return "NO_FULSH";
}
void DebugPrint(_MyFILE* file)
{
    printf("outbuffer:%s\n", file->buffer);
    printf("fileno:%d\n", file->fileno);
    printf("pos:%d\n", file->pos);
    printf("cap:%d\n", file->cap);
    printf("flush_mode:%s\n", toString(file->flush_mode));
}
_MyFILE *MyFopen(const char *pathname, const char *mode)
{
    // 打开文件
    int flag = 0;
    int fd = -1;
    if (strcmp("r", mode) == 0)
    {
        fd = open(pathname, O_RDONLY);
    }
    else if (strcmp("w", mode) == 0)
    {
        umask(0000);
        fd = open(pathname, O_CREAT | O_WRONLY | O_TRUNC, 0666);
    }

    else if (strcmp("a", mode) == 0)
    {
        umask(0000);
        fd = open(pathname, O_CREAT | O_WRONLY | O_APPEND, 0666);
    }
    else
    {
        return NULL;
    }

    // 构建FILE结构体
    _MyFILE *file = (_MyFILE *)malloc(sizeof(_MyFILE));
    if (file == NULL)
        return NULL;
    file->fileno = fd;
    file->cap = BUFFERSIZE;
    file->pos = 0;
    file->flush_mode = LINE_FLUSH;
    file->buffer = malloc(file->cap);

    return file;
}

void MyFlush(_MyFILE *file)
{
    write(file->fileno, file->buffer, file->pos);
    file->pos = 0;
}

void MyFclose(_MyFILE *file)
{
    MyFlush(file);
    free(file->buffer);
    close(file->fileno);
    free(file);
}
int MyFwrite(_MyFILE *file, const void *str, unsigned int size)
{
    if (str == NULL || file == NULL || size == 0)
        return 0;

    // 1.拷贝到缓冲区
    // 1.1判断扩容
    if (file->pos + size > file->cap)
    {
        int new_cap = file->cap;
        // 确保申请的容量一定够
        while (file->pos + size > new_cap)
        {
            new_cap *= 2;
        }
        void* temp = realloc(file->buffer, new_cap);
        if (temp == NULL)
        {
            // 申请空间失败
            return -1;
        }

        file->buffer = temp;
        file->cap = new_cap;
    }
    // 1.2拷贝数据
    memcpy(file->buffer + file->pos, str, size);
    file->pos += size;
    // 2.判断是否需要刷新
    if (file->flush_mode == LINE_FLUSH && ((char*)str)[size - 1] == '\n')
    {
        MyFlush(file);
    }
    else if (file->flush_mode == FULL_FLUSH && file->pos == file->cap)
    {
        MyFlush(file);
    }
    return size;
}